
#include "lua_c_api/include/lua.hpp"

// base class to bridge between a Reaper object and the Luasphere
class Bridger
{
	void	*theReaperObject;
public:
	Bridger(lua_State *L);
	void *GetReaperObject(void);
	void SetReaperObject(void *ptr);
};
// remember the Bridge object is a {table} not a userdata
// the userdata is element[0] of the {table}
// toReaperObject() will dig out the pointer from the userdata

void *toReaperObject(lua_State *L, int idx);

void setupUserdata(lua_State *L, void *reaperObjPtr);

// the {self} table must be at the top of the stack

void addToString(lua_State *L, int cf(lua_State *L) );

// takes luna{BridgerSubclass} returns string

#define mktostring(TYPESTRING)	\
	static int fBridge##TYPESTRING##__tostring ( lua_State *L ) {	\
		void *rop = toReaperObject(L, 1);					\
		lua_pushfstring(L, "%s 0x%p", #TYPESTRING, rop);	\
		return 1;											\
	}

// think if there's a way to put these strings in Lua and package them
// in a closure with the tostring.


#define mkpusher(TYPESTRING)	\
int push##TYPESTRING ( lua_State *L , TYPESTRING *p ) {					\
	Luna< Bridge##TYPESTRING > :: constructor(L);		/* {self} */	\
	setupUserdata(L, p);								/* {self} */	\
	addToString(L, fBridge##TYPESTRING##__tostring);	/* {self} */	\
	return 1;	}

#define mksetup(TYPESTRING)	\
	void setup##TYPESTRING ( lua_State *L )	{											\
	Luna< Bridge##TYPESTRING >::Register(L);	/* userdata's metatable on stack */		\
	lua_pop(L, 1);	}							/* nice clean stack */

#define mkchelpers(TYPESTRING)	\
	mktostring(TYPESTRING);		\
	mkpusher(TYPESTRING);		\
	mksetup(TYPESTRING);
